﻿#ifndef RTMPMSG_H
#define RTMPMSG_H

#include <string>

enum RTMP_BODY_TYPE
{
    RTMP_BODY_METADATA, // metadata
    RTMP_BODY_AUD_RAW,  // raw data
    RTMP_BODY_AUD_SPEC, // AudioSpecificConfig
    RTMP_BODY_VID_RAW,  // raw data
    RTMP_BODY_VID_CONFIG// AVCDecoderConfigurationRecord
};

enum RTMPChannel
{
   RTMP_NETWORK_CHANNEL = 2,   ///< channel for network-related messages (bandwidth report, ping, etc)
   RTMP_SYSTEM_CHANNEL,        ///< channel for sending server control messages
   RTMP_AUDIO_CHANNEL,         ///< channel for audio data
   RTMP_VIDEO_CHANNEL   = 6,   ///< channel for video data
   RTMP_SOURCE_CHANNEL  = 8,   ///< channel for a/v invokes
};

class FLVMetadataMsg
{
public:
    FLVMetadataMsg(){}
    ~FLVMetadataMsg(){}

    bool has_audio = false;
    bool has_video = false;
    int audiocodeid = -1;
    int audiodatarate = 0;
    int audiodelay = 0;
    int audiosamplerate = 0;
    int audiosamplesize = 0;
    int channles;
    int profile;

    bool canSeekToEnd = 0;

    std::string creationdate;
    int duration = 0;
    int64_t filesize = 0;
    double framerate = 0;
    int height = 0;
    bool stereo = true;

    int videocodecid = -1;
    int64_t videodatarate = 0;
    int width = 0;
    int64_t pts = 0;
};

class AudioSpecMsg
{
public:
    AudioSpecMsg(uint8_t profile, uint8_t channel_num, uint32_t samplerate)
    {
        profile_ = profile;
        channels_ = channel_num;
        sample_rate_ = samplerate;
    }

    ~AudioSpecMsg(){}

    uint8_t profile_ = 2;   //2 : AAC LC(Low Complexity)
    uint8_t channels_ = 2;
    uint32_t sample_rate_ = 48000;
    int64_t pts_;
};

class AudioRawMsg
{
public:
    AudioRawMsg(int size, int with_adts = 0)
    {
        this->size = size;
        type = 0;
        with_adts_ = with_adts;
        data = (unsigned char*)malloc(size * sizeof(char));
    }

    AudioRawMsg(const unsigned char*buf, int bufLen, int with_adts = 0)
    {
        this->size = bufLen;
        type = buf[4] & 0x1f;
        with_adts_ = with_adts;
        data = (unsigned char*)malloc(bufLen*sizeof(char));
        memcpy(data,buf,bufLen);
    }

    ~AudioRawMsg()
    {
        if(data)
            free(data);
    }

    int type;
    int size;
    int with_adts_ = 0;
    unsigned char *data = NULL;
    uint32_t pts;
};

class VideoSequenceHeaderMsg
{
public:
    VideoSequenceHeaderMsg(uint8_t *sps, int sps_size, uint8_t* pps, int pps_size)
    {
        sps_ = (uint8_t *)malloc(sps_size*sizeof(uint8_t));
        pps_ = (uint8_t *)malloc(pps_size*sizeof(uint8_t));

        sps_size_ = sps_size;
        memcpy(sps_, sps, sps_size);
        pps_size_ = pps_size;
        memcpy(pps_, pps, pps_size);
    }

    ~VideoSequenceHeaderMsg()
    {
        if(sps_)
            free(sps_);
        if(pps_)
            free(pps_);
    }

    uint8_t* sps_;
    int sps_size_;
    uint8_t* pps_;
    int pps_size_;
    unsigned int    nWidth;
    unsigned int    nHeight;
    unsigned int    nFrameRate;     // fps
    unsigned int    nVideoDataRate; // bps
    int64_t pts_ = 0;
};

class VideoRawMsg
{
public:
    VideoRawMsg(uint8_t *buf, int bufLen)
    {
        size = bufLen;
        data = (uint8_t *)malloc(bufLen * sizeof(uint8_t));
        memcpy(data, buf, bufLen);
        type = buf[4] & 0x1f;
    }

    ~VideoRawMsg()
    {
        if(data)
        {
            free(data);
            data = NULL;
        }
    }

    int type;
    int size;
    uint8_t *data;
    uint32_t pts;
};


#endif // RTMPMSG_H
